package edu.corn.job.core.processor.adapter;

import edu.corn.job.core.context.JobRunningContext;
import edu.corn.job.core.engine.JobEngine;
import edu.corn.job.core.processor.AbstractJobProcessor;
import lombok.Data;

/**
 * 抽象类抽象出组合job和PhaseJob共同需要的特征。
 * 日志记录操作。
 * 同步操作。
 * 挂起操作。
 * 持久化操作。
 */
@Data
public abstract class AbstractJobAdapter implements JobAdapter {


    /**
     * 当前执行器对应的job。
     */
    protected AbstractJobProcessor job;


    /**
     * job引擎。
     */
    private JobEngine engine;

    /**
     * 类初始化会将所有子类都实例化job。
     *
     * @param job
     */
    public AbstractJobAdapter(AbstractJobProcessor job, JobEngine engine) {
        this.job = job;
        this.engine = engine;
    }


    @Override
    public void executeJob(JobRunningContext context) {
        // 获取锁
        boolean b = tryLock(job);
        if (!b) {
            // TODO 挂起。
            return;
        }
        try {

            // 执行handler 是否主动重试？
            int retryCount = 0;
            while (retryCount < engine.getConfig().getRetryCount() && !doJobInternal(context)) {
                retryCount++;
                // 还原重试路径上的可能存在的job状态。
            }
        } finally {
            // 执行到这已经获取锁了，所以把锁释放。
            unlock(job);
        }

    }

    /**
     * 内部执行计划。
     * 当将子类的
     *
     * @param context
     * @return
     */
    public abstract boolean doJobInternal(JobRunningContext context);


    @Override
    public String save() {


        return "";
    }

    @Override
    public void load(String jobName) {

    }

    @Override
    final public AbstractJobProcessor getJobProcessor() {
        return job;
    }


    protected void unlock(AbstractJobProcessor processor) {
        if (processor != null) {
            engine.getMutexPool().unlock(processor);
        }
    }

    protected boolean tryLock(AbstractJobProcessor processor) {
        if (processor != null) {
            return engine.getMutexPool().lock(processor);
        }
        return true;
    }

}
